﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DSP.MathLibrary;
using System.Diagnostics;

namespace DataLayer
{
    public class MeteoDataRaw
    {
        public MeteoDataRaw()
        {
            this.DataRow = new List<ComplexNumber>();
            this.SourceDataRow = new List<ObservationPoint>();
            IsAdjusted = false;
        }

        public double Avg { get; set; }
        public DateTime dtBegin { get; set; }
        public DateTime dtEnd { get; set; }
        
        /// <summary>
        /// Timestep in hours
        /// </summary>
        public double TimeStep { get; set; }

        public List<ComplexNumber> DataRow { get; private set; }

        public List<ObservationPoint> SourceDataRow { get; set; }

        public bool IsAdjusted { get; private set; }

        public void Adjust()
        {

            if (!this.IsAdjusted)
            {
                this.dtBegin = this.SourceDataRow.Min(item => item.DateTime);
                this.dtEnd = this.SourceDataRow.Max(item => item.DateTime);
                this.Avg = this.SourceDataRow.Where(item => !double.IsNaN(item.Value)).Average(item => item.Value);

                this.SourceDataRow = this.SourceDataRow.OrderBy(item => item.DateTime).ToList();
                this.SourceDataRow = this.SourceDataRow.Select(item => new ObservationPoint
                                                                    {
                                                                        Value = double.IsNaN(item.Value) ? 0 : item.Value - Avg,
                                                                        DateTime = item.DateTime
                                                                    }).ToList();

                DateTime dt = dtBegin;
                int i = 0;
                int h = (int)TimeStep;

                while (dt <= dtEnd)
                {
                    if (this.SourceDataRow[i].DateTime == dt)
                    {
                        this.DataRow.Add(new ComplexNumber(this.SourceDataRow[i].Value, 0));
                        i++;
                    }
                    else
                    {
                        this.DataRow.Add(new ComplexNumber(0, 0));
                       // Debug.WriteLine(this.SourceDataRow[i].DateTime.ToString() + " : " + dt.ToString());
                       
                    }
                    dt = dt.AddHours(h);
                }

                IsAdjusted = true;
            }
        }

        public Dictionary<int,List<ObservationPoint>> SplitDataIntoStandardTimes()
        {
            this.Adjust();
            Dictionary<int, List<ObservationPoint>> result = new Dictionary<int, List<ObservationPoint>>();

            // = new ObservationPoint[this.SourceDataRow.Count];
            List<ObservationPoint> periodicList =  new List<ObservationPoint>();
           

            int hoursInYear = 365 * 24;

            DateTime dtStart = this.dtBegin.AddDays(-this.dtBegin.DayOfYear - 1);
            dtStart = dtStart.Date;

            DateTime dt = dtStart;
           
            for (int i = 0; i < this.SourceDataRow.Count; i++)
            {
                dt = this.SourceDataRow[i].DateTime;
                if (!(dt.Month == 2 && dt.Day == 29))
                {
                    periodicList.Add(this.SourceDataRow[i]);
                  
                }
               
            }

            ObservationPoint[] periodicArray = periodicList.ToArray();

            periodicList.Clear();
            periodicList = null;
          

            for (int h = 0; h < hoursInYear; h += (int)this.TimeStep)
            {
                dt = dt.AddHours(this.TimeStep);
                if (dt.Month == 2 && dt.Day == 29)
                {
                    dt = dt.AddDays(1);
                }

                int hh = h;
                while (hh < periodicArray.Count())
                {
                    if (!result.ContainsKey(h))
                    {
                        result.Add(h, new List<ObservationPoint>());
                    }
                    result[h].Add(periodicArray[hh]);
                    hh += hoursInYear/3;
                }

                
            }

            return result;
        }
    }
}
